// VestaOPCLink.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "VestaOPCLink.h"

// windows 
#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include <objbase.h>
#include <olectl.h>
#include <comcat.h>
#include <atlconv.h>
#include <atlbase.h>

// OPC
#include "opcda.h"
#include "opcda_i.c"

// STL and boost
#include <exception>
#include <vector>
#include <string>
#include <iostream>
#include <iostream>
#include <sstream>
#include <algorithm>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>

// Data interface
#include "../VestaOPC/DataInterfaceTypeInfo_h.h"    // use your own path here
#include "../VestaOPC/DataInterfaceTypeInfo_i.c"  // use your own path here

using namespace std;
using namespace boost::algorithm;
using std::vector;
using std::wstring;
using std::cout;
using std::endl;

struct connection_context_t {
	connection_context_t() 
		: pDataInterface(0)
	{ }
	IDataInterface* pDataInterface;
};


VESTAOPCLINK_API void* OpenDataConnection() {
	connection_context_t* connection_context = new connection_context_t;

	HRESULT hr;

	connection_context->pDataInterface = 0;
	hr = CoCreateInstance(CLSID_DataInterface, NULL, CLSCTX_LOCAL_SERVER, 
		IID_IDataInterface, (LPVOID *)&connection_context->pDataInterface);
	if (SUCCEEDED(hr))
		return reinterpret_cast<void *> (connection_context);
	else
		return NULL;
}

VESTAOPCLINK_API void CloseDataConnection(void* context) {
	connection_context_t* connection_context = 
		reinterpret_cast<connection_context_t *> (context);

	if (connection_context->pDataInterface) {
	   connection_context->pDataInterface->Release();
	   connection_context->pDataInterface = 0;
	}

	delete context;

}

VESTAOPCLINK_API BOOL ConfigureOPCInterface(void* context, tag_config_t* configuration, 
						   unsigned configuration_size)  
{
	connection_context_t* connection_context = 
		reinterpret_cast<connection_context_t *> (context);

	if (!connection_context)
		return FALSE;
	if (!connection_context->pDataInterface)
		return FALSE;

	return SUCCEEDED(
			connection_context->pDataInterface->Configure(
				configuration_size, configuration)
		);
}

VESTAOPCLINK_API BOOL WriteData(void* context, unsigned values_count, tag_value_t* values) 
{
	connection_context_t* connection_context = 
		reinterpret_cast<connection_context_t *> (context);
	return SUCCEEDED(
		connection_context->pDataInterface->Write(values_count, values)
		);
}

VESTAOPCLINK_API BOOL ReadData(void* context, unsigned values_count, tag_value_t* values) 
{
	connection_context_t* connection_context = 
		reinterpret_cast<connection_context_t *> (context);
	return SUCCEEDED(
		connection_context->pDataInterface->Read(values_count, values)
		);
}

